//------------------------------------------------------------------------------
// <copyright file="HeroComponent.cs" company="Damian Antonowicz">
//       copyright © 2010 Damian Antonowicz
// </copyright>
// <author>Damian Antonowicz</author>
// <email>poczta@damianantonowicz.pl</email>
//------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using DotBeer.Business.Entities;
using DotBeer.Data;
using DotBeer.Data.Properties;
using DotBeer.Business.Components.Exceptions;
using System.Diagnostics;

namespace DotBeer.Business.Components
{
    public class HeroComponent
    {
        #region private members

        static StringBuilder stringBuilder;
        static string separator;

        #endregion

        #region constructors

        public HeroComponent()
        {
        }

        #endregion

        #region public methods

        public static void Save(Hero hero)
        {
            try
            {
                AbstractDataAccess<Hero> heroDAL = new HeroDataAccess();
                heroDAL.Save(hero);
            }
            catch (Exception ex)
            {
                HandleExceptions.BusinessLogicPolicy(ex);
            }
        }

        public static Hero Load(string heroName)
        {
            return LoadHero(heroName);
        }

        public static Hero Load(string heroName, string authorName)
        {
            return LoadHero(heroName, authorName);
        }

        public static Hero LoadDefaultHero(string heroName)
        {
            return new Hero() { Name = heroName };
        }

        public static bool Delete(string heroName, string authorName)
        {
            Authors authors = Authors.Instance;
            authors.Remove(authorName);

            string filePath = String.Format(@"{0}Heroes\{1} by {2}.xml", AppDomain.CurrentDomain.BaseDirectory, heroName, authorName);
            bool result = false;

            if (File.Exists(filePath))
            {
                try
                {
                    File.Delete(filePath);
                    result = true;
                }
                catch(Exception ex)
                {
                    HandleExceptions.BusinessLogicPolicy(ex);
                }
            }
            else
            {
                throw new FileNotFoundException(String.Format("File to delete: {0} not found.", filePath));
            }

            return result;
        }

        public static void CopyItemBuildToClipboard(Hero hero)
        {
            stringBuilder = new StringBuilder();
            separator = CopyItemBuildSettings.Default.Separator;

            Action<string> addMethod;

            if (CopyItemBuildSettings.Default.Orientation == "Vertical")
                addMethod = new Action<string>(AddVertical);
            else
                addMethod = new Action<string>(AddHorizontal);

            for (int i = 0; i < hero.CurrentItems.Count; i++)
            {
                if (CopyItemBuildSettings.Default.CopyAs == "Image")
                {
                    addMethod(String.Format("{0}{1}{2}{3}{4}/{5}{6}",
                                            CopyItemBuildSettings.Default.StartBracket,
                                            CopyItemBuildSettings.Default.SyntaxWord,
                                            CopyItemBuildSettings.Default.EndBracket,
                                            hero.CurrentItems[i].Url,
                                            CopyItemBuildSettings.Default.StartBracket,
                                            CopyItemBuildSettings.Default.SyntaxWord,
                                            CopyItemBuildSettings.Default.EndBracket));
                }
                else
                {
                    if (CopyItemBuildSettings.Default.Numerate)
                    {
                        addMethod(String.Format("{0}. {1}", (i + 1).ToString(), hero.CurrentItems[i].Name));
                    }
                    else
                    {
                        addMethod(String.Format("{0}", hero.CurrentItems[i].Name));
                    }
                }
            }

            Clipboard.Clear();
            Clipboard.SetText(stringBuilder.ToString(), TextDataFormat.UnicodeText);
        }

        public static void CopySkillBuildToClipboard(Hero hero)
        {
            stringBuilder = new StringBuilder();
            separator = CopySkillBuildSettings.Default.Separator;

            Action<string> addMethod;

            if (CopySkillBuildSettings.Default.Orientation == "Vertical")
                addMethod = new Action<string>(AddVertical);
            else
                addMethod = new Action<string>(AddHorizontal);

            for (int i = 0; i < hero.CurrentSkills.Count; i++)
            {
                if (CopySkillBuildSettings.Default.Numerate)
                {
                    addMethod(String.Format("{0} {1}. {2}",
                                CopySkillBuildSettings.Default.SyntaxWord,
                                (i + 1).ToString(),
                                hero.CurrentSkills[i].Name));
                }
                else
                {
                    addMethod(String.Format("{0}. {1}",
                                CopySkillBuildSettings.Default.SyntaxWord,
                                hero.CurrentSkills[i].Name));
                }
            }

            Clipboard.Clear();
            Clipboard.SetText(stringBuilder.ToString(), TextDataFormat.UnicodeText);
        }

        public static IEnumerable<ItemHero> GetFilteredCurrentItems(Hero hero)
        {
            if (hero != null)
            {
                List<string> types = new List<string>(GetDisplayTypes());

                foreach (ItemHero item in hero.CurrentItems.Where(i => types.Contains(i.Type) || DisplayOptionsSettings.Default.ShowAll)
                                                           .Select(i => i).ToList())
                {
                    yield return item;
                }
            }
        }

        #endregion

        #region private methods

        private static Hero LoadHero(params object[] list)
        {
            AbstractDataAccess<Hero> heroDAL = new HeroDataAccess();

            Hero hero = null;

            try
            {
                hero = heroDAL.Load(list);
            }
            catch (Exception ex)
            {
                HandleExceptions.BusinessLogicPolicy(ex);
            }

            return hero;
        }

        private static void AddHorizontal(string text)
        {
            stringBuilder.Append(String.Format("{0}{1} ", text, separator));
        }

        private static void AddVertical(string text)
        {
            stringBuilder.AppendLine(text);
        }

        private static IEnumerable<string> GetDisplayTypes()
        {
            if (DisplayOptionsSettings.Default.ShowAfterwards)
                yield return "Afterwards";

            if (DisplayOptionsSettings.Default.ShowCore)
                yield return "Core";

            if (DisplayOptionsSettings.Default.ShowCustom)
                foreach (string s in DisplayOptionsSettings.Default.CustomTypes.Split(';').ToList())
                    yield return s;

            if (DisplayOptionsSettings.Default.ShowOptional)
                yield return "Optional";
        }

        #endregion
    }
}
